home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / mmlc / source / m2comp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-29  |  21.3 KB  |  1,010 lines

  1. /* ------------------------------------------------------------------
  2.                         MML compiler [M2]
  3.                programmed by S.Yamamoto (SHINNOSUKE)
  4.                  m2comp.c  --  MML compile Main
  5. ------------------------------------------------------------------ */
  6.  
  7. #include    <stdio.h>
  8. #include    <stdlib.h>
  9. #include    <ctype.h>
  10. #include    <string.h>
  11. #include    <limits.h>
  12. #include    "m2.h"
  13.  
  14. #define    SUCCSESS    0
  15. #define    FAILURE    (-1)
  16. #define    TRUE    1
  17. #define    FALSE    0
  18. #define    ERR    (-1)
  19. #define    YES    1
  20. #define    NO    0
  21.  
  22. #define    PART_MAX    16
  23. #define    ARAY_MAX    16
  24. #define    EXCL_MAX    128
  25.  
  26. #define    EXCM    0xf0
  27. #define    TEMPO    0xf7
  28. #define    SIGNATURE    0xf8
  29. #define    MEMO    0xf1
  30. #define    WORDS    0xf2
  31. #define    F7EXCM    0xf3
  32. #define    DIRECT    0xf4
  33.  
  34. #define    ABS(x)    ((x)>0?(x):-(x))
  35. #define    CHECKSUM(x)    (((x)%128!=0)?128-(x)%128:0) /* EXCLUSIVE SUM */
  36.  
  37. #define    RUNNING    1
  38. #define    SHIFTST    2
  39. #define    HISPCMP    4
  40. #define    CHECKMD    8
  41.  
  42. char    *EMG_v = "velocity";
  43. char    *EMG_o = "octave";
  44. char    *EMG_q = "q";
  45. char    *EMG_l = "length";
  46.  
  47. char    *rp;
  48. char    *exclPt[EXCL_MAX];    /* Exclusive pointer */
  49.  
  50. char    key_spart[16] = {0,0,0,0 ,0,0,0,0 ,0,0,0,0 ,0,0,0,0};
  51. int    key_shift = 0;
  52.  
  53. int    dlt_v[PART_MAX][ARAY_MAX];
  54. int    dlt_o[PART_MAX][ARAY_MAX];
  55. int    dlt_q[PART_MAX][ARAY_MAX];
  56. int    dlt_l[PART_MAX][ARAY_MAX];
  57.  
  58. int    tie_flag;
  59. int    tie_note;
  60. int    tie_etct;    /* タイコマンド用 */
  61.  
  62. int    exclCt;        /* Exclusive count */
  63. int    nowPart;
  64. int    nowAray;
  65. int    dltAray[PART_MAX];
  66.  
  67. int    evntCt;
  68.  
  69. int option;    /* option status */
  70.  
  71. unsigned    short    maxTCt;
  72. unsigned    short    setTime[128];
  73.  
  74. WORKMEM    *evntBuf;
  75. FLGDAT    fg;
  76.  
  77. static    int    ctrlMacro[][7] =
  78. {/* Num,Mode,Min,Max,+(para default),*,default */
  79.     {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
  80.     {0,0,0,127,0,1,0},    /* b/Bank Select */
  81.     {10,1,ERR,ERR,64,1,ERR},    /* c/Panpot Center */
  82.     {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
  83.     {11,0,0,127,0,1,127},    /* e/Expression */
  84.     {69,0,0,1,0,127,0},    /* f/freeze */
  85.     {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
  86.     {64,0,0,1,0,127,0},    /* h/Hold1 */
  87.     {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
  88.     {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
  89.     {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
  90.     {10,0,0,64,64,-1,63},    /* l/Panpot Left */
  91.     {1,0,0,127,0,1,0},    /* m/Modulation depth */
  92.     {66,0,0,1,0,127,0},    /* n/Sostenuto */
  93.     {93,0,0,127,0,1,0},    /* o/chorus send level(ef3) */
  94.     {65,0,0,1,0,127,0},    /* p/Portamento */
  95.     {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
  96.     {10,0,0,63,64,1,63},    /* r/Panpot Right */
  97.     {67,0,0,1,0,127,0},    /* s/Soft pedal */
  98.     {5,0,0,127,0,1,0},    /* t/portamento time */
  99.     {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
  100.     {7,0,0,127,0,1,100},    /* v/volume */
  101.     {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
  102.     {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
  103.     {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
  104.     {ERR,ERR,ERR,ERR,ERR,ERR,ERR}
  105. };
  106.  
  107. void    dltSet( void )    /* 省略値の初期化 */
  108. {
  109.     int    i;
  110.     int    j;
  111.  
  112.     for( i=0;i<PART_MAX;i++ ) {
  113.         for( j=0;j<ARAY_MAX;j++ ) {
  114.             dlt_v[i][j] = 127;
  115.             dlt_o[i][j] = 4;
  116.             dlt_q[i][j] = 8;
  117.             dlt_l[i][j] = 4;
  118.         }
  119.     }
  120.     return;
  121. }
  122.  
  123. /* データ読み込み・書き込みなど */
  124.  
  125. int    readData( void )    /* 文字の読み込み */
  126. {
  127.     int    ret;
  128.  
  129.     skipLine( &rp );
  130.     ret = *rp;
  131.     return( ret );
  132. }
  133.  
  134. int    readPara( int min ,int max ,int d ,char *m )    /* 数字の読み込み */
  135. {
  136.     int    ret;
  137.  
  138.     skipLine( &rp );
  139.     ret = strToInt( &rp ,min ,max ,d ,m );
  140.     return( ret );
  141. }
  142.  
  143. int    blockName( void )    /* ブロックネームを読み飛ばす */
  144. {
  145.     int    b;
  146.     int    flag = 0;
  147.  
  148.     for(;;) {
  149.         b = readData();
  150.         if( b == '{' )
  151.             break;
  152.         if( b == '\0' )
  153.             return( FAILURE );
  154.         rp++;
  155.         if( b< ' ' || b > '~' )
  156.             continue;
  157.         if( flag == 0 )
  158.             putDisp( "process:" );
  159.         putDisp( "%c",b );
  160.         flag = 1;
  161.     }
  162.     rp++;
  163.     if( flag == 1 )
  164.         putDisp("\n");
  165.     return( SUCCSESS );
  166. }
  167.  
  168. void    getPart( void )    /* パート&配列番号を得る */
  169. {
  170.     nowPart = readPara( 1 ,PART_MAX ,-1 ,"(part number)" ) - 1;
  171.  
  172.     if( readData() == '[' ) {
  173.         rp++;
  174.         dltAray[nowPart] = readPara( 0 ,ARAY_MAX-1 ,dltAray[nowPart]
  175.             ,"(array number)" );
  176.         if( readData() != ']' )
  177.             errMsg( MSG_syntax ,"array" );
  178.         rp++;
  179.     };
  180.  
  181.     nowAray = dltAray[nowPart];
  182.     dltAray[nowPart]++;
  183.     if( dltAray[nowPart] >= ARAY_MAX )
  184.         dltAray[nowPart]=0;
  185.  
  186.     if( readData() != '=' )
  187.         errMsg( MSG_misopd ,"not found '='" );
  188.     rp++;
  189.     return;
  190. }
  191.  
  192. void    exclBank( unsigned short t ,int m ,int l ,char *s )
  193. {
  194.     int    i;
  195.  
  196.     evntPut( t ,m ,exclCt ,l);
  197.     if(( exclPt[exclCt] = malloc( l )) == NULL)
  198.         errMsg( MSG_cntalc ,"excl/word" );
  199.  
  200.     for( i=0;i<l;i++ ) {
  201.         exclPt[exclCt][i] = *s;
  202.         s++;
  203.     }
  204.     exclCt++;
  205.     return;
  206. }
  207.  
  208. /* イベント処理系 */
  209.  
  210. void    evntPut(unsigned short c ,int d1 ,int d2 ,int d3 )    /* 記憶 */
  211. {
  212.     if( evntCt >= fg.wksize )
  213.         errMsg( MSG_outwka ,NULL );
  214.  
  215.     evntBuf[evntCt].num = (unsigned short) evntCt;
  216.     evntBuf[evntCt].ct = (unsigned short) c;
  217.     evntBuf[evntCt].dat[0] = (unsigned char) d1;
  218.     evntBuf[evntCt].dat[1] = (unsigned char) d2;
  219.     evntBuf[evntCt].dat[2] = (unsigned char) d3;
  220.     evntCt++;
  221.     return;
  222. }
  223.  
  224. void    evntSort( void )    /* イベントをソート */
  225. {
  226. /*  基本選択法  */
  227.     int    i;
  228.     int    j;
  229.     int    s;
  230.  
  231.     unsigned    short    min;
  232.     WORKMEM    dummy;
  233.     
  234.     for( i=0;i<evntCt-1;i++ ) {
  235.         min = evntBuf[i].ct;
  236.         s = i;
  237.         for( j=i+1;j<evntCt;j++ ) {
  238.             if( evntBuf[j].ct < min || (evntBuf[j].ct == min
  239.             && evntBuf[j].num < evntBuf[s].num )) {
  240.                 min = evntBuf[j].ct;
  241.                 s = j;
  242.             }
  243.         }
  244.         dummy = evntBuf[i];
  245.         evntBuf[i] = evntBuf[s];
  246.         evntBuf[s] = dummy;
  247.     }
  248.     return;
  249. }
  250.  
  251. void    evntSort2( void )    /* イベントをソート(高速モード) */
  252. {
  253. /*  ヒープソート  
  254.     動作チェックで,完全に安定したソートができていないことがわかった。
  255. */
  256.     int    i;
  257.     int    j;
  258.     int    k;
  259.     int    n = evntCt;
  260.  
  261.     WORKMEM    x;
  262.  
  263.     for ( k=n/2;k>=1;k-- ) {
  264.         i = k;
  265.         x = evntBuf[i-1];
  266.         while((j = 2 * i) <= n) {
  267.             if (j< n && evntBuf[j-1].ct < evntBuf[j].ct) j++;
  268.             if (evntBuf[j-1].ct == evntBuf[j].ct) {
  269.                 if(j < n && evntBuf[j-1].num <= evntBuf[j].num )
  270.                     j++;
  271.             }
  272.             if (x.ct > evntBuf[j-1].ct) break;
  273.             if (x.ct == evntBuf[j-1].ct) {
  274.                 if(x.num >= evntBuf[j-1].num)    break;
  275.             }
  276.             evntBuf[i-1] = evntBuf[j-1];
  277.             i = j;
  278.         }
  279.         evntBuf[i-1] = x;
  280.     }
  281.     while (n > 1) {
  282.         x = evntBuf[n-1];
  283.         evntBuf[n-1] = evntBuf[0];
  284.         n--;
  285.         i = 1;
  286.         while ((j = 2 * i) <= n) {
  287.             if (j < n && evntBuf[j-1].ct < evntBuf[j].ct) j++;
  288.             if (evntBuf[j-1].ct == evntBuf[j].ct) {
  289.                 if(j < n && evntBuf[j-1].num <= evntBuf[j].num) j++;
  290.             }
  291.             if (x.ct > evntBuf[j-1].ct) break;
  292.             if (x.ct == evntBuf[j-1].ct) {
  293.                 if(x.num >= evntBuf[j-1].num)    break;
  294.             }
  295.             evntBuf[i-1] = evntBuf[j-1];
  296.             i = j;
  297.         }
  298.         evntBuf[i-1] = x;
  299.     }
  300.     return;
  301. }
  302.  
  303. void    evntCheck( void )    /* イベントをチェック */
  304. {
  305.     unsigned    int    i;
  306.     unsigned    int    c = 0;
  307.     unsigned    int    n = 0;
  308.  
  309.     printf( "No.   Time  Pri.  MIDI Para.\n" );
  310.  
  311.     for( i=0;i<evntCt;i++ ) {
  312.         printf( "%05u %05u %05u %02X %03u %03u\n",i ,evntBuf[i].ct
  313.             ,evntBuf[i].num ,evntBuf[i].dat[0]
  314.             ,evntBuf[i].dat[1] ,evntBuf[i].dat[2] );
  315.  
  316.         if ( i != 0 ) {
  317.             if( c == evntBuf[i].ct ) {
  318.                 if( n > evntBuf[i].num )
  319.                     printf( "Warning:Sort error\n" );
  320.             }
  321.         }
  322.         c = evntBuf[i].ct;
  323.         n = evntBuf[i].num; 
  324.     }
  325.     return;
  326. }
  327.  
  328. void    evntRtch( void )    /* イベントを修正 */
  329. {
  330.     int    e;
  331.     int    i;
  332.     int    flag = FALSE;
  333.  
  334.     unsigned    short    max;
  335.     unsigned    short    t1;
  336.     unsigned    short    t2;
  337.  
  338.     max = evntBuf[evntCt-1].ct;
  339.     for( i=0;i<evntCt-2;i++ ) {
  340.         e = (evntBuf[i].dat[0]) & 0xf0;
  341.         if( e==0xb0 || e==0xc0 || e==0xe0 || e==0xf0 ) {
  342.             if( flag == FALSE ) {
  343.                 t1 = evntBuf[i].ct;
  344.                 t2 = evntBuf[i].ct;
  345.                 flag = TRUE;
  346.                 continue;
  347.             }
  348.             if( t1 == evntBuf[i].ct ) {
  349.                 t2++;
  350.                 if( t2 <= max )    evntBuf[i].ct = t2;
  351.                 continue;
  352.             }
  353.             t1 = evntBuf[i].ct;
  354.             if( t1 > t2 )    t2 = evntBuf[i].ct;
  355.         }
  356.     }
  357.     evntSort();
  358.     return;
  359. }
  360.  
  361. void    evntWrite(void)    /* イベントをディスクに出力 */
  362. {
  363.     int    ev;
  364.     int    i;
  365.     int    j;
  366.     int    dummy;
  367.     int    running = -1;
  368.  
  369.     unsigned    long    dt;
  370.  
  371.     for( i=0;i<evntCt;i++ ) {
  372.         dt = ( i==0 ) ? 0 : evntBuf[i].ct-evntBuf[i-1].ct;
  373.         dt = dt * fg.div /48;    /* 分解能変換 */
  374.         varNum( dt );    /* TIME */
  375.         ev = evntBuf[i].dat[0];
  376.         if( ev >= 0x80 && ev <= 0xef) {
  377.             if(( running!=ev ) || (( option & RUNNING ) != RUNNING)) {
  378.                 putData( 1,ev );
  379.                 running = ev;
  380.             }
  381.             if(( ev&0xf0 ) == 0xc0 ) {
  382.                 putData( 1 ,evntBuf[i].dat[1] );
  383.                 continue;
  384.             }
  385.             putData( 2 ,evntBuf[i].dat[1] ,evntBuf[i].dat[2] );
  386.             continue;
  387.         }
  388.         running = -1;
  389.         if( ev == 0xff ) {
  390.             for( j=0;j<3;j++ )
  391.                 putData( 1 ,evntBuf[i].dat[j] );
  392.             continue;
  393.         }
  394.         switch( ev ) {
  395.         case EXCM:    /* exclusive message */
  396.             putData( 1 ,0xf0 );
  397.             dummy = (int) evntBuf[i].dat[1];
  398.             varNum( (unsigned long) evntBuf[i].dat[2] + 1 );
  399.             for( j=0;j<(int)evntBuf[i].dat[2];j++ )
  400.                 putData( 1 ,(int)exclPt[dummy][j] );
  401.             putData( 1 ,0xf7 );
  402.             break;
  403.         case F7EXCM:
  404.             putData( 1 ,0xf7 );
  405.             dummy = (int) evntBuf[i].dat[1];
  406.             varNum( (unsigned long) evntBuf[i].dat[2] );
  407.             for( j=0;j<(int)evntBuf[i].dat[2];j++ )
  408.                 putData( 1 ,(int) exclPt[dummy][j] );
  409.             break;
  410.         case DIRECT:
  411.             dummy = (int) evntBuf[i].dat[1];
  412.             for( j=0;j<(int)evntBuf[i].dat[2];j++ )
  413.                 putData( 1 ,(int)exclPt[dummy][j] );
  414.             break;
  415.         case MEMO:    /* text */
  416.         case WORDS:    /* words */
  417.             dummy = ( ev==WORDS ) ? 5 : 1;
  418.             putData( 2,0xff,dummy );
  419.             dummy = (int) evntBuf[i].dat[1];
  420.             varNum( (unsigned long) evntBuf[i].dat[2] );
  421.             for( j=0;j<(int)evntBuf[i].dat[2];j++ )
  422.                 putData( 1 ,(int)exclPt[dummy][j] );
  423.             break;
  424.         case TEMPO:    /* tempo */
  425.             putTempo( evntBuf[i].dat[1] * 256 + evntBuf[i].dat[2] );
  426.             break;
  427.         case SIGNATURE:    /* signature */
  428.             putSignature( evntBuf[i].dat[1] ,evntBuf[i].dat[2] );
  429.         case 0xf9:    /* tyou */
  430.             break;
  431.         }
  432.     }
  433.     return;
  434. }
  435.  
  436. /*  MMLコマンド類 */
  437.  
  438. void    mmlNote( unsigned short *tc ,int note )    /* ノートオン・オフ/休符 */
  439. {
  440.     int    d;
  441.     int    n;
  442.     int    len;
  443.     int    vel;
  444.     int    q;
  445.     int    step;
  446.     int    dummy;
  447.  
  448.     unsigned    short    timeCt;
  449.     unsigned    short    tDummy;
  450.  
  451.     timeCt = *tc;
  452.     n = note;
  453.  
  454.     if( n == 12 ) {
  455.         note = readPara( 0 ,127 ,-1 ,"'n' number" );
  456.         if( readData() == ',' )    rp++;
  457.     }
  458.  
  459.     if( n<12 ) {
  460.         if( (d = readData()) == '+' || d == '#' ){
  461.             note++;
  462.             rp++;
  463.         }
  464.         if( d=='-' ){
  465.             note--;
  466.             rp++;
  467.         }
  468.         note += (dlt_o[nowPart][nowAray]+1) * 12;
  469.         if(key_spart[nowPart] == 0)    note = note + key_shift;
  470.         if(note<0 || note>127)    errMsg(MSG_syntax,"over note");
  471.     }
  472.  
  473.     step = 0;
  474.     for(;;){
  475.         len = readPara( 1 ,192 ,dlt_l[nowPart][nowAray]
  476.             ,"(note:length)" );
  477.         dummy = 192 / len;
  478.         if( readData() == '.' ) {
  479.             rp++;
  480.             dummy = dummy * 1.5;
  481.         }
  482.         step += dummy;
  483.         if( readData() =='^' )    rp++;
  484.         else    break;
  485.     }
  486.  
  487.     if( n != 13 ){
  488.         if( readData() == ',' ) {
  489.             rp++;
  490.             vel = readPara( 1 ,127 ,dlt_v[nowPart][nowAray]
  491.                 ,"(note:velocity)" );
  492.         }else    vel = dlt_v[nowPart][nowAray];
  493.         if( readData() == ',' ) {
  494.             rp++;
  495.             q = readPara( 1 ,8 ,dlt_q[nowPart][nowAray]
  496.                 ,"(note:q)");
  497.         }else    q=dlt_q[nowPart][nowAray];
  498.  
  499.         if( tie_flag == TRUE ) {
  500.             if( tie_note == note )
  501.                 evntBuf[tie_etct].ct = (unsigned short)( timeCt+step*q/8 );
  502.             else {
  503.                 if( tie_note != ERR )
  504.                     evntBuf[tie_etct].ct = (unsigned short)(timeCt);
  505.                 q = 8;
  506.                 tie_flag = FALSE;
  507.             }
  508.         }
  509.         if( tie_flag != TRUE ) {
  510.             evntPut( timeCt ,0x90+fg.part[nowPart] ,note ,vel );
  511.             tie_note = note;
  512.             tie_etct = evntCt;
  513.             tDummy = step*q/8-1;
  514.             if( tDummy < 1 )    tDummy = 1;
  515.             evntPut( timeCt+tDummy ,0x80+fg.part[nowPart]
  516.                 ,note ,0x00 );
  517.         }
  518.     }
  519.     timeCt += step;
  520.     *tc = timeCt;
  521.     tie_flag = FALSE;
  522.     return;
  523. }
  524. void    mmlSub1( unsigned short timeCt ,int cm )    /* MMLコマンド1 */
  525. {
  526.     char    *msg_tempo = "tempo";
  527.  
  528.     int    dummy;
  529.     int    para;
  530.  
  531.     switch( cm )
  532.     {
  533.         case 'v':
  534.             dlt_v[nowPart][nowAray] = readPara( 0,15,15,EMG_v )*8+7;
  535.             break;
  536.         case 'o':
  537.             dlt_o[nowPart][nowAray] = readPara( 1,8,4,EMG_o);
  538.             break;
  539.         case 'q':
  540.             dlt_q[nowPart][nowAray] = readPara( 1,8,8,EMG_q );
  541.             break;
  542.         case 'l':
  543.             dlt_l[nowPart][nowAray] = readPara( 1,192,4,EMG_l );
  544.             break;
  545.         case '>':
  546.             dlt_o[nowPart][nowAray] += 2;
  547.         case '<':
  548.             dlt_o[nowPart][nowAray] --;
  549.             dummy = dlt_o[nowPart][nowAray];
  550.             if( dummy < 1 || dummy > 8 )
  551.                 errMsg( MSG_illfnc ,"'>or<' octave over" );
  552.             break;
  553.         case ']':
  554.         case '[':
  555.             dummy = readPara( 0,127,8,EMG_v )*((cm==']')?1:-1);
  556.             dummy += dlt_v[nowPart][nowAray];
  557.             if( dummy<0 || dummy>127 )
  558.                 errMsg( MSG_illfnc ,"']or[' velocity over" );
  559.             dlt_v[nowPart][nowAray] = dummy;
  560.             break;
  561.         case 'u':
  562.             para = readPara( -8192,8191,0,"pitch bend" )+8192;
  563.             evntPut( timeCt,0xE0+fg.part[nowPart],para&0x7f,(para&0x3f80)>>7 );
  564.             break;
  565.         case 't':
  566.             dummy = readData();
  567.             if( dummy=='+' || dummy=='-' ) {
  568.             rp++;
  569.             para = readPara( 0,256,5,msg_tempo );
  570.             fg.tempo += para*(( dummy=='+' )?1:-1);
  571.             } else
  572.                 fg.tempo = readPara( 30,600,120,msg_tempo );
  573.             evntPut( timeCt,TEMPO,(fg.tempo&0xff00)>>8,fg.tempo&0xff );
  574.             break;
  575.         default:
  576.             errMsg( MSG_unperr ,NULL );
  577.     }
  578.     return;
  579. }
  580.  
  581. void    mmlSub2( unsigned short timeCt )    /* MMLコマンド2 */
  582. {
  583.     char    *msg_c = "control change";
  584.     char    *msg_s = "signature";
  585.     char    *msg_x = "exclusive";
  586.     char    *msg_m = "memo or words";
  587.  
  588.     char    ex[256];
  589.  
  590.     int    cm2;
  591.     int    para;
  592.     int    para2;
  593.     int    dummy;
  594.     int    i;
  595.     int    j;
  596.  
  597.     cm2 = tolower(readData());
  598.     rp++;
  599.     switch( cm2 ) {
  600.         case 'a':
  601.             para = readPara( 0,127,0,NULL );
  602.             break;
  603.         case 'c':
  604.             para = readPara( 0,127,-1,msg_c );
  605.             if( readData() != '/' )
  606.                 errMsg( MSG_syntax,msg_c );
  607.                 rp++;
  608.             para2 = readPara( 0,127,-1,msg_c );
  609.             evntPut( timeCt,0xB0+fg.part[nowPart],para,para2 );
  610.             break;
  611.         case 'v':
  612.             dlt_v[nowPart][nowAray] = readPara( 0,127,127,EMG_v );
  613.             break;
  614.         case 's':
  615.             para = readPara( 1,64,-1,msg_s );
  616.             if( readData() != '/' )
  617.                 errMsg( MSG_syntax ,msg_s );
  618.             rp++;
  619.             para2 = readPara( 1,64,-1,msg_s );
  620.             evntPut( timeCt,SIGNATURE,para,para2 );
  621.             fg.signature[0] = para;
  622.             fg.signature[1] = para2;
  623.             break;
  624.         case 'd':
  625.         case 'r':
  626.         case 'f':
  627.         case 'x':
  628.             if( readData() != '[' )
  629.                 errMsg( MSG_syntax,msg_x );
  630.             rp++;
  631.             i=0;
  632.             for(;;) {
  633.                 dummy = readData();
  634.                 if( dummy == ']' )    break;
  635.                 if( dummy == '\0' ) {
  636.                     skipLine( &rp );
  637.                     continue;
  638.                 }
  639.                 para = 0;
  640.                 for( j=0;j<2;j++ ) {
  641.                     dummy = readData();
  642.                     rp++;
  643.                     if( dummy == '%' ) {
  644.                         if( j != 0 )
  645.                             errMsg( MSG_syntax,msg_x );
  646.                         para=readPara( 0,255,-1,msg_x );
  647.                         if( readData() != '%' )
  648.                             errMsg( MSG_syntax,msg_x );
  649.                         rp++;
  650.                         break;
  651.                     }
  652.                     if( toupper(dummy) == 'X' ) {
  653.                         dummy=fg.part[nowPart];
  654.                         dummy=(dummy != 9)?dummy:-1;
  655.                         if(dummy<9)    dummy++;
  656.                     }
  657.                     else if( toupper(dummy) == 'P' ) {
  658.                         dummy = fg.part[nowPart];
  659.                     }
  660.                     else
  661.                         dummy = instr("0123456789ABCDEF",toupper(dummy));
  662.                     if( dummy == ERR )
  663.                         errMsg( MSG_syntax,msg_x );
  664.                     para = para*16+dummy;
  665.                 }
  666.                 ex[i] = para;
  667.                 if( ++i > 255 )
  668.                     errMsg( MSG_syntax,msg_x );
  669.             }
  670.             rp++;
  671.             if ( cm2 == 'r' ) {    /* ROLAND EX. CHECK SUM */
  672.                 if( i == 255 )
  673.                     errMsg(MSG_syntax,msg_x);
  674.                 dummy = 0;
  675.                 for( j=4;j<i;j++ )    dummy += ex[j];
  676.                 dummy = CHECKSUM(dummy);
  677.                 ex[i++] = dummy;
  678.             }
  679.             if( cm2 == 'f' )    dummy = F7EXCM;
  680.             else if( cm2 == 'd' )    dummy = DIRECT;
  681.             else dummy = EXCM;
  682.             exclBank( timeCt,dummy,i,ex );
  683.             break;
  684.         case 'm':    /* メモ・歌詞はエクスクルーシブ領域を代用する */
  685.         case 'w':
  686.             if( readData() != '"' )
  687.                 errMsg( MSG_syntax,msg_m );
  688.             rp++;
  689.             i = 0;
  690.             for(;;) {
  691.                 dummy=*rp;
  692.                 if( dummy=='"' )    break;
  693.                 if( dummy=='\0' )    {
  694.                     skipLine( &rp );
  695.                     continue;
  696.                 }
  697.                 rp++;
  698.                 ex[i] = dummy;
  699.                 if( ++i > 255 )    break;
  700.             }
  701.             rp++;
  702.             dummy = (cm2=='w')?WORDS:MEMO;
  703.             exclBank( timeCt,dummy,i,ex );
  704.             break;
  705.         case 'h':
  706.             fg.part[nowPart] = readPara( 1,16,0,"'@H'" )-1;
  707.             break;
  708.         case 'k':
  709.             dummy = toupper(readData());
  710.             rp++;
  711.             if(  dummy == 'S' ) {
  712.                 para = readPara( 1,16,0,"'@KS'")-1;
  713.                 key_spart[para]=1;
  714.             } else 
  715.             if( dummy == 'U' || dummy == 'D' )
  716.                 key_shift = readPara(0,24,-1,"'@KU/@KD'") * ((dummy == 'U')?1:-1);
  717.             else    errMsg(MSG_syntax,"Key Shift");
  718.             break;
  719.         default:
  720.             rp--;
  721.             dummy = readPara( 0,128,-1,"program change" );
  722.             para = fg.program[dummy]-1;
  723.             if( para<0 || para >127 )
  724.                 errMsg( MSG_illfnc,"program change" );
  725.             evntPut( timeCt,0xC0+fg.part[nowPart],para,0x00 );
  726.             break;
  727.     }
  728.     return;
  729. }
  730. void    mmlSub3( unsigned int t )    /* ”%”コマンド */
  731. {
  732.     int    comNum;
  733.     int    clChg;
  734.     int    mode;
  735.     int    min;
  736.     int    max;
  737.     int    a;
  738.     int    b;
  739.     int    defl;
  740.     int    para = 0;
  741.  
  742.     comNum = toupper( readData() );
  743.  
  744.     if( comNum ==ERR || comNum < 'A' || comNum > 'Z' )
  745.         errMsg( MSG_syntax ,"('%')" );
  746.     rp++;
  747.  
  748.     comNum = comNum - 'A';
  749.     clChg = ctrlMacro[comNum][0];
  750.     mode = ctrlMacro[comNum][1];
  751.     min = ctrlMacro[comNum][2];
  752.     max = ctrlMacro[comNum][3];
  753.     a = ctrlMacro[comNum][4];
  754.     b = ctrlMacro[comNum][5];
  755.     defl = ctrlMacro[comNum][6];
  756.  
  757.     if( clChg == ERR )
  758.         errMsg( MSG_syntax ,"('%')" );
  759.     if( mode != 1 )
  760.         para = readPara( min ,max ,defl ,"('%' para)" );
  761.     para = para * b + a;
  762.     evntPut( t ,0xB0+fg .part[nowPart] ,clChg ,para );
  763.     return;
  764. }
  765.  
  766. void    mmlSub4( unsigned short *tc )    /* タイムポインター系 */
  767. {
  768.     int    c;
  769.     int    d;
  770.     unsigned    short    timeCt;
  771.  
  772.     timeCt = *tc;
  773.     c = tolower( readData() );
  774.     rp++;
  775.  
  776.     switch( c ) {
  777.         case 's':
  778.             d = readPara( 1 ,128 ,0 ,"MARK" ) - 1;
  779.             setTime[d] = timeCt;
  780.             break;
  781.         case 'm':
  782.             timeCt = ( readPara( 1,256,0,"MEAS" ) -1 ) * fg.signature[0] * 192 / fg.signature[1];
  783.             break;
  784.         case 'i':
  785.             printf( "info.  :Time/%u O/%d L/%d @V/%d Q/%d\n",timeCt,
  786.                 dlt_o[nowPart][nowAray] ,dlt_l[nowPart][nowAray],
  787.                 dlt_v[nowPart][nowAray] ,dlt_q[nowPart][nowAray]);
  788.             break;
  789.         default:
  790.             rp--;
  791.             d = readPara( 1,128,0,"MARK" ) - 1;
  792.             timeCt = setTime[d];
  793.             break;
  794.     }
  795.     *tc = timeCt;
  796.     return;
  797. }
  798.  
  799. void    mmlRhythm( unsigned short *tc ,int cm )    /* リズム用サブコマンド */
  800. {
  801.     char    *msg = "Rhythm Track";
  802.     char    buf[64];
  803.  
  804.     int    num = 1;
  805.     int    len;
  806.     int    step;
  807.     int    dummy;
  808.     int    note;
  809.     int    vel;
  810.     int    i;
  811.  
  812.     buf[0] = cm;
  813.  
  814.     for(;;) {
  815.         cm = tolower( readData() );
  816.  
  817.         if( cm == '!' ) {
  818.             rp++;
  819.             continue;
  820.         }
  821.  
  822.         if( cm == 'r' )
  823.             errMsg( MSG_syntax ,msg );
  824.  
  825.         if( cm >= 'a' && cm <= 'z' ) {
  826.             buf[num] = cm;
  827.             num++;
  828.             if( num >= 64 )
  829.                 errMsg( MSG_syntax ,msg );
  830.             rp++;
  831.             continue;
  832.         }
  833.         break;
  834.     }
  835.  
  836.     step = 0;
  837.  
  838.     for(;;) {
  839.         len = readPara( 1 ,192 ,0 ,msg );
  840.         dummy = 192 / len;
  841.  
  842.         if( readData()=='.') {
  843.             rp++;
  844.             dummy = dummy * 1.5;
  845.         }
  846.         step += dummy;
  847.         if( readData() == '^' )
  848.             rp++;
  849.         else    break;
  850.     }
  851.  
  852.     for( i=0;i<num;i++ ) {
  853.         dummy = buf[i] - 'a';
  854.         note = fg.rnote[dummy][0];
  855.         vel = fg.rnote[dummy][1];
  856.         if( note == ERR )
  857.             errMsg( MSG_undmml ,"Rhythm" );
  858.         evntPut( *tc ,0x90+fg .part[nowPart] ,note ,vel );
  859.         evntPut( *tc+1 ,0x80+fg .part[nowPart] ,note ,0x00 );
  860.     }
  861.     *tc += step;
  862.     return;
  863. }
  864.  
  865. void    mmlComp( void )    /* MMLコマンド分岐 */
  866. {
  867.     char    buf[32];
  868.  
  869.     int    cm;
  870.     int    note;
  871.     int    maxSTC = 0;
  872.  
  873.     unsigned    short    timeCt = 0;
  874.     unsigned    short    sTimeCt[32][2];
  875.  
  876.     tie_flag = FALSE;
  877.     tie_note = ERR;
  878.  
  879.     for(;;) {
  880.         if( timeCt > maxTCt )
  881.             maxTCt = timeCt;
  882.         cm = tolower( readData() );
  883.         if( cm == '\0' )
  884.             errMsg( MSG_freerr ,"MML not end" );
  885.         if( cm == '}' ) {
  886.             printf( "Warning:" );
  887.             printf( MSG_misopd ,"';'" );
  888.             break;
  889.         }
  890.         rp++;
  891.         if( cm == ';' )
  892.             break;
  893.         if( fg.rpart == nowPart ) {
  894.             if( cm >= 'a' && cm <= 'z' && cm != 'r' ) {
  895.                 mmlRhythm( &timeCt ,cm );
  896.                 continue;
  897.             }
  898.         }
  899.         if(( note = instr( "c d ef g a bnr" ,cm )) != ERR ) {
  900.             mmlNote( &timeCt ,note );
  901.             continue;
  902.         }
  903.         if( instr( "voql><[]ut" ,cm ) != ERR ) {
  904.             mmlSub1( timeCt ,cm );
  905.             continue;
  906.         }
  907.         if( cm == '@' ) {
  908.             mmlSub2( timeCt );
  909.             continue;
  910.         }
  911.         if( cm == '%' ) {
  912.             mmlSub3( timeCt );
  913.             continue;
  914.         }
  915.         if( cm == '*' ) {
  916.             mmlSub4( &timeCt );
  917.             continue;
  918.         }
  919.         if( cm == '&' ) {
  920.             tie_flag=TRUE;
  921.             continue;
  922.         }
  923.         if( cm == '_' ) {
  924.             itlMacro( &rp ,&timeCt ,&exclCt ,fg.part[nowPart] );
  925.             continue;
  926.         }
  927.         switch( cm ) {
  928.             case '(':
  929.                 if( maxSTC >= 32 )
  930.                     errMsg( MSG_toonst ,"Chord" );
  931.                 sTimeCt[maxSTC][0] = timeCt;
  932.                 sTimeCt[maxSTC][1] = timeCt;
  933.                 maxSTC++;
  934.                 break;
  935.             case '|':
  936.                 if( maxSTC == 0 )
  937.                     errMsg( MSG_syntax ,"chord:'|'" );
  938.                 if( timeCt > sTimeCt[maxSTC-1][1] )
  939.                     sTimeCt[maxSTC-1][1] = timeCt;
  940.                 timeCt = sTimeCt[maxSTC-1][0];
  941.                 break;
  942.             case ')':
  943.                 if( maxSTC == 0 )
  944.                     errMsg( MSG_syntax ,"chord:')'" );
  945.                 maxSTC--;
  946.                 timeCt = sTimeCt[maxSTC][1];
  947.                 break;
  948.         }
  949.         if( instr( "(|)" ,cm ) != ERR )
  950.             continue;
  951.  
  952.         sprintf( buf ,"undefined MML '%c'" ,cm );
  953.         errMsg( MSG_syntax ,buf );
  954.     }
  955.     if( maxSTC != 0 ) {
  956.         printf( "Warning:" );
  957.         printf( MSG_misopd ,"chord" );
  958.     }
  959.     if( timeCt > maxTCt )
  960.         maxTCt = timeCt;
  961.     return;
  962. }
  963.  
  964. int    mmlLine( FLGDAT fgDummy ,WORKMEM *w ,int orf )    /* MML行メイン */
  965. {
  966.     int    i;
  967.  
  968.     option = orf;
  969.     evntBuf = w;
  970.     fg = fgDummy;
  971.  
  972.     if(( rp = Pre_fgets() ) == NULL )
  973.         errMsg( MSG_freerr ,"No MML data" );
  974.     dltSet();
  975.  
  976.     for( i=0;i<128;i++ )
  977.         setTime[i] = 0;
  978.  
  979.     for(;;) {
  980.         if( blockName() == FAILURE )
  981.             break;
  982.         for( i=0;i<PART_MAX;i++ )
  983.             dltAray[i] = 0;    /* 配列初期化 */
  984.         evntCt = 0;
  985.         exclCt = 0;
  986.         maxTCt = 0;
  987.         for(;;) {
  988.             if( readData() == '}' ) {
  989.                 rp++;
  990.                 break;
  991.             }
  992.             getPart();
  993.             mmlComp();
  994.         }
  995.         evntPut( maxTCt ,0xff ,0x06 ,0x00 );
  996.  
  997.         if(( option & HISPCMP ) != HISPCMP )
  998.             evntSort();
  999.         else    evntSort2();
  1000.         if(( option & SHIFTST ) == SHIFTST )
  1001.             evntRtch();
  1002.         evntWrite();
  1003.         if(( option & CHECKMD ) == CHECKMD )
  1004.             evntCheck();
  1005.         for( i=0;i<exclCt;i++ )
  1006.             free( exclPt[i] );
  1007.     }
  1008.     return( SUCCSESS );
  1009. }
  1010.